import numpy as np
from collections import Counter

class MyKNN:
    """
    自定义K近邻分类器实现
    """
    def __init__(self, n_neighbors=5):
        self.n_neighbors = n_neighbors  # 近邻数K
        self.X_train = None
        self.y_train = None

    def fit(self, X, y):
        """存储训练数据"""
        self.X_train = X
        self.y_train = y
        return self

    def predict(self, X):
        """预测新样本类别"""
        predictions = []
        for x in X:
            # 计算当前样本与所有训练样本的欧氏距离
            distances = [self._euclidean_distance(x, x_train) for x_train in self.X_train]
            
            # 获取距离最近的K个样本的索引
            k_indices = np.argsort(distances)[:self.n_neighbors]
            
            # 提取对应的类别标签并统计多数票
            k_nearest_labels = self.y_train[k_indices]
            most_common_label = Counter(k_nearest_labels).most_common(1)[0][0]
            predictions.append(most_common_label)
        return np.array(predictions)

    @staticmethod
    def _euclidean_distance(a, b):
        """欧氏距离计算"""
        return np.sqrt(np.sum((a - b)**2))

# ===================== 使用示例 =====================
# 使用自定义KNN模型 (K=7)
custom_knn = MyKNN(n_neighbors=7)
custom_knn.fit(X_train_scaled, y_train)
y_pred_custom = custom_knn.predict(X_test_scaled)

# 计算准确率
accuracy_custom = np.mean(y_pred_custom == y_test)
print(f"自定义KNN准确率: {accuracy_custom:.4f}")

# 对比scikit-learn官方实现
from sklearn.neighbors import KNeighborsClassifier
sklearn_knn = KNeighborsClassifier(n_neighbors=7)
sklearn_knn.fit(X_train_scaled, y_train)
y_pred_sklearn = sklearn_knn.predict(X_test_scaled)
accuracy_sklearn = np.mean(y_pred_sklearn == y_test)
print(f"官方KNN准确率: {accuracy_sklearn:.4f}")